home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / emulator / uae-0.000 / uae-0 / uae-0.6.0 / bebox.cpp < prev    next >
C/C++ Source or Header  |  1996-06-12  |  14KB  |  636 lines

  1. /* 
  2.  * UAE - The Un*x Amiga Emulator
  3.  *
  4.  * BeBox port specific stuff
  5.  * 
  6.  * (c) 1996 Christian Bauer
  7.  */
  8.  
  9. #include <AppKit.h>
  10. #include <InterfaceKit.h>
  11. #include <KernelKit.h>
  12.  
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <string.h>
  16. #define __STDC__ 1
  17. #define __GNU_LIBRARY__
  18. #include <getopt.h>
  19. #undef __GNU_LIBRARY__
  20. #undef __STDC__
  21.  
  22. #ifndef __bebox__
  23. #error Compiling bebox.cpp, but __bebox__ unset.
  24. #endif
  25.  
  26. extern "C" {
  27. #include "sysconfig.h"
  28. #include "sysdeps.h"
  29. #include "config.h"
  30. #include "options.h"
  31. #include "memory.h"
  32. #include "custom.h"
  33. #include "newcpu.h"
  34. #include "disk.h"
  35. #include "debug.h"
  36. #include "xwin.h"
  37. #include "os.h"
  38. #include "filesys.h"
  39. #include "keybuf.h"
  40. #include "keyboard.h"
  41. }
  42.  
  43.  
  44. class UAEWindow;
  45. class BitmapView;
  46. class Emulator;
  47.  
  48.  
  49. /*
  50.  *  The BeOS application object
  51.  */
  52.  
  53. class UAE : public BApplication {
  54. public:
  55.     UAE();
  56.     virtual void ArgvReceived(int argc, char **argv);
  57.     virtual void ReadyToRun(void);
  58.     virtual bool QuitRequested(void);
  59.     virtual void AboutRequested(void);
  60.  
  61. private:
  62.     BBitmap *the_bitmap;
  63.     UAEWindow *main_window;
  64.     Emulator *the_emulator;
  65. };
  66.  
  67.  
  68. /*
  69.  *  The window in which the Amiga graphics are displayed, handles I/O
  70.  */
  71.  
  72. class UAEWindow : public BWindow {
  73. public:
  74.     UAEWindow(BRect frame, BBitmap *bitmap);
  75.     virtual bool QuitRequested(void);
  76.     virtual void WindowActivated(bool active);
  77.  
  78. private:
  79.     BitmapView *main_view;
  80. };
  81.  
  82.  
  83. /*
  84.  *  A simple view class for blitting a bitmap on the screen
  85.  */
  86.  
  87. class BitmapView : public BView {
  88. public:
  89.     BitmapView(BRect frame, BBitmap *bitmap);
  90.     virtual void Draw(BRect update);
  91.     void Draw(BRect from, BRect to);
  92.  
  93. private:
  94.     BBitmap *the_bitmap;
  95. };
  96.  
  97.  
  98. /*
  99.  *  For running the emulation in its own thread
  100.  */
  101.  
  102. class Emulator {
  103. public:
  104.     Emulator() {thread_running = FALSE;}
  105.     void Run(void);
  106.     void Quit(void);
  107.  
  108. private:
  109.     static long thread_invoc(Emulator *obj);
  110.     void thread_func(void);
  111.  
  112.     thread_id the_thread;
  113.     bool thread_running;
  114. };
  115.  
  116.  
  117. // Keyboard and mouse
  118. int buttonstate[3];
  119. int newmousecounters;
  120. int lastmx, lastmy;
  121.  
  122. key_info old_key_info;
  123. bool inwindow;
  124. bool window_open;
  125.  
  126. // Color map and bitmap
  127. xcolnr xcolors[4096];
  128. struct vidbuf_description gfxvidinfo;
  129.  
  130. int vsize, hsize, hpixels;
  131.  
  132. BitmapView *bitmap_view;
  133. UAEWindow *bitmap_window;
  134.  
  135.  
  136. // Array for converting Be keycodes to Amiga keycodes
  137. int keycode2amiga[128] = {
  138.     -1, AK_ESC, AK_F1, AK_F2, AK_F3, AK_F4, AK_F5, AK_F6,
  139.     AK_F7, AK_F8, AK_F9, AK_F10, AK_LALT, AK_mousestuff, AK_RALT, -1,
  140.  
  141.     -1, AK_BACKQUOTE, AK_1, AK_2, AK_3, AK_4, AK_5, AK_6,
  142.     AK_7, AK_8, AK_9, AK_0, AK_MINUS, AK_EQUAL, AK_BS, AK_HELP,
  143.  
  144.     AK_NPLPAREN, AK_RAMI, AK_NPLPAREN, AK_NPDIV, AK_NPMUL, AK_NPSUB, AK_TAB, AK_Q,
  145.     AK_W, AK_E, AK_R, AK_T, AK_Y, AK_U, AK_I, AK_O,
  146.  
  147.     AK_P, AK_LBRACKET, AK_RBRACKET, AK_BACKSLASH, AK_DEL, AK_NPRPAREN, AK_LAMI, AK_NP7,
  148.     AK_NP8, AK_NP9, AK_NPADD, AK_CAPSLOCK, AK_A, AK_S, AK_D, AK_F,
  149.  
  150.     AK_G, AK_H, AK_J, AK_K, AK_L, AK_SEMICOLON, AK_QUOTE, AK_RET,
  151.     AK_NP4, AK_NP5, AK_NP6, AK_LSH, AK_Z, AK_X, AK_C, AK_V,
  152.  
  153.     AK_B, AK_N, AK_M, AK_COMMA, AK_PERIOD, AK_SLASH, AK_RSH, AK_UP,
  154.     AK_NP1, AK_NP2, AK_NP3, AK_ENT, AK_CTRL, AK_LAMI, AK_SPC, AK_RAMI,
  155.  
  156.     AK_RALT, AK_LF, AK_DN, AK_RT, AK_NP0, AK_NPDEL, AK_LALT, AK_RALT,
  157.     AK_LTGT, -1, -1, -1, -1, -1, -1, -1,
  158.  
  159.     -1, -1, -1, -1, -1, -1, -1, -1,
  160.     -1, -1, -1, -1, -1, -1, -1, -1
  161. };
  162.  
  163.  
  164. /*
  165.  *  Create application object and start it
  166.  */
  167.  
  168. main()
  169. {
  170.     UAE *the_app;
  171.     
  172.     the_app = new UAE();
  173.     the_app->Run();
  174.     delete the_app;
  175.     
  176.     return 0;
  177. }
  178.  
  179.  
  180. /*
  181.  *  UAE Constructor: Initialize member variables
  182.  */
  183.  
  184. UAE::UAE() : BApplication('UAEm')
  185. {
  186.     the_bitmap = NULL;
  187.     the_emulator = NULL;
  188.     main_window = NULL;
  189.     window_open = FALSE;
  190. }
  191.  
  192.  
  193. /*
  194.  *  Parse command line options
  195.  */
  196.  
  197. void usage(void)
  198. {
  199.     printf("UAE - The Un*x Amiga emulator\n");
  200.     printf("Summary of command-line options:\n");
  201.     printf("  -h                       : Print help\n");
  202.     printf("  -m VOLNAME:mount_point   : mount file system at <mount point> as AmigaDOS\n"
  203.            "                             volume VOLNAME:\n");
  204.     printf("  -M VOLNAME:mount_point   : like -m, but mount read-only\n");
  205.     printf("  -a                       : Don't mount the harddisk file automatically.\n"
  206.            "                             Useful only for testing.\n");
  207.     printf("  -s                       : Emulate 1MB slow memory at 0xC00000\n");
  208.     printf("  -F n                     : Emulate n MB fast memory at 0x200000\n");
  209.     printf("  -f n                     : Set the frame rate to 1/n\n");
  210.     printf("  -d                       : Draw the screen with the right aspect\n");
  211.     printf("  -D                       : Start up the built-in debugger\n");
  212.     printf("  -[0123] file             : Use file instead of df[0123].adf as disk image file\n");
  213.     printf("  -r file                  : Use file as ROM image instead of kick.rom\n");
  214.     printf("  -p filename              : Use filename to save printer output (may be LPT1: ?)\n");
  215.     printf("  -J                       : Fake joystick emulation with the numeric pad.\n");
  216.     printf("  -g                       : Turn on gfx-lib replacement.\n");
  217.     printf("  -d mode                  : Select resolution with the mode parameter.\n");
  218.     printf("  -H mode                  : Set the number of colors with the mode parameter.\n");
  219.     printf("\n");
  220.     printf("Valid resolutions: 0 (320x200); 1 (320x240); 2 (320x400); 3 (800x600);\n"
  221.        "                   4 (800x600, correct aspect)\n"
  222.        "Valid color modes: 0 (256 colors); 1 (32768 colors); 2 (65536 colors)\n"
  223.        "UAE may choose to ignore the color mode/resolution setting.\n");
  224. }
  225.  
  226. void UAE::ArgvReceived(int argc, char **argv)
  227. {
  228.     int c;
  229.  
  230.     while(((c = getopt(argc, argv, "Df:gd:hF:asJm:M:0:1:2:3:r:H:p:")) != EOF)) switch(c) {
  231.      case 'h': usage();    exit(0);
  232.  
  233.      case '0': strncpy(df0, optarg, 255); df0[255] = 0;    break;
  234.      case '1': strncpy(df1, optarg, 255); df1[255] = 0; break;
  235.      case '2': strncpy(df2, optarg, 255); df2[255] = 0; break;
  236.      case '3': strncpy(df3, optarg, 255); df3[255] = 0; break;
  237.      case 'r': strncpy(romfile, optarg, 255); romfile[255] = 0; break;
  238.      case 'p': strncpy(prtname, optarg, 255); prtname[255] = 0; break;            
  239.      case 'm':
  240.      case 'M':
  241.     {
  242.         /* mount file system (repeatable)
  243.          * syntax: [-m | -M] VOLNAME:/mount_point
  244.          * example: -M CDROM:/cdrom -m UNIXFS:./disk
  245.          */
  246.         static int mount_seen = 0;
  247.         char buf[256];
  248.         char *s2;
  249.         int readonly = (c == 'M');
  250.         
  251.         if (mount_seen)
  252.         fprintf(stderr, "warning: multiple mounts confuse Kickstart 1.3\n");
  253.         mount_seen = 1;
  254.         strncpy(buf, optarg, 255); buf[255] = 0;
  255.         s2 = strchr(buf, ':');
  256.         if(s2) {
  257.         *s2++ = '\0';
  258.         add_filesys_unit(buf, s2, readonly);
  259.         } else {
  260.         fprintf(stderr, "Usage: [-m | -M] VOLNAME:/mount_point\n");
  261.         }
  262.     }
  263.     break;
  264.     
  265.      case 'f': framerate = atoi(optarg); break;
  266.      case 'D': use_debugger = 1; break;
  267.      case 'J': fake_joystick = 1; break;
  268.      case 'a': automount_uaedev = 0; break;
  269.      case 's': use_slow_mem = 1; break;
  270.      case 'g': use_gfxlib = 1; break;
  271.  
  272.      case 'F':
  273.     fastmem_size = atoi(optarg) * 0x100000;
  274.     if (fastmem_size != 0x100000 && fastmem_size != 0x200000 
  275.         && fastmem_size != 0x400000 && fastmem_size != 0x800000) 
  276.     {
  277.         fastmem_size = 0;
  278.         fprintf(stderr, "Unsupported fastmem size!\n");
  279.     }
  280.     
  281.     break;
  282.     
  283.      case 'd':
  284.     screen_res = atoi(optarg);
  285.     if (screen_res >= 0 && screen_res <= 4) {
  286.     } else {
  287.         fprintf(stderr, "Bad video mode selected. Using default.\n");
  288.         screen_res = 3;
  289.     }
  290.     dont_want_aspect = screen_res != 4;
  291.     use_lores = screen_res < 3;
  292.     break;
  293.  
  294.      case 'H':
  295.     color_mode = atoi(optarg);
  296.     if (color_mode < 0 || color_mode > 2) {
  297.         fprintf(stderr, "Bad color mode selected. Using default.\n");
  298.         color_mode = 0;
  299.     }
  300.     break;
  301.     }
  302. }
  303.  
  304.  
  305. /*
  306.  *  Arguments processed, create and start emulation
  307.  */
  308.  
  309. void UAE::ReadyToRun(void)
  310. {
  311.     vsize = dont_want_aspect ? numscrlines : numscrlines*2;
  312.     hsize = use_lores ? 400 : 800;
  313.     hpixels = use_lores ? 320 : 796;
  314.  
  315.     // Allocate bitmap
  316.     the_bitmap = new BBitmap(BRect(0, 0, hsize-1, vsize-1), B_COLOR_8_BIT);
  317.  
  318.     // Set up vidinfo
  319.     gfxvidinfo.bufmem =  (char *)the_bitmap->Bits();
  320.     gfxvidinfo.rowbytes = the_bitmap->BytesPerRow();
  321.     gfxvidinfo.pixbytes = 1;
  322.     gfxvidinfo.maxblocklines = 100;
  323.  
  324.     // Open window
  325.     main_window = new UAEWindow(BRect(0, 0, hpixels-1, vsize-1), the_bitmap);
  326.  
  327.     // Initialize mouse and keyboard variables
  328.     buttonstate[0] = buttonstate[1] = buttonstate[2] = FALSE;
  329.     lastmx = lastmy = 0;
  330.     newmousecounters = FALSE;
  331.     inwindow = TRUE;
  332.  
  333.     // Start emulation
  334.     the_emulator = new Emulator;
  335.     the_emulator->Run();
  336. }
  337.  
  338.  
  339. /*
  340.  *  Quit requested (either by menu or by closing the window)
  341.  */
  342.  
  343. bool UAE::QuitRequested(void)
  344. {
  345.     if (BApplication::QuitRequested()) {
  346.  
  347.         // Stop emulation
  348.         if (the_emulator) {
  349.             the_emulator->Quit();
  350.             delete the_emulator;
  351.         }
  352.  
  353.         // Deallocate bitmap
  354.         if (the_bitmap)
  355.             delete the_bitmap;
  356.  
  357.         return TRUE;
  358.     }
  359.     return FALSE;
  360. }
  361.  
  362.  
  363. /*
  364.  *  Display "about" window
  365.  */
  366.  
  367. void UAE::AboutRequested(void)
  368. {
  369.     char str[256];
  370.  
  371.     sprintf(str, "UAE V0.5.3 by Bernd Schmidt\nBeBox port by Christian Bauer");
  372.     BAlert *the_alert = new BAlert("", str, "OK");
  373.     the_alert->Go();
  374. }
  375.  
  376.  
  377. /*
  378.  *  UAE Window constructor
  379.  */
  380.  
  381. UAEWindow::UAEWindow(BRect frame, BBitmap *bitmap) : BWindow(frame, "UAE", B_TITLED_WINDOW, B_NOT_RESIZABLE)
  382. {
  383.     int r, g, b, i;
  384.  
  385.     // Move window to right position
  386.     MoveTo(80, 60);
  387.  
  388.     // Create bitmap view
  389.     Lock();
  390.     main_view = new BitmapView(frame, bitmap);
  391.     AddChild(main_view);
  392.     main_view->GetKeys(&old_key_info, FALSE);
  393.     Unlock();
  394.  
  395.     bitmap_view = main_view;
  396.     bitmap_window = this;
  397.  
  398.     // Initialize xcolors
  399.     i = 0;
  400.     for (r=0; r<16; r++) {
  401.         for (g=0; g<16; g++) {
  402.             for (b=0; b<16; b++)
  403.                 xcolors[i++] = index_for_color(r<<4 | r, g<<4 | g, b<<4 | b);
  404.         }
  405.     }
  406.  
  407.     // Show window
  408.     Show();
  409.     window_open = TRUE;
  410. }
  411.  
  412.  
  413. /*
  414.  *  Closing the window quits UAE
  415.  */
  416.  
  417. bool UAEWindow::QuitRequested(void)
  418. {
  419.     window_open = FALSE;
  420.     be_app->PostMessage(B_QUIT_REQUESTED);
  421.     return TRUE;
  422. }
  423.  
  424.  
  425. /*
  426.  *  Window was (de)activated
  427.  */
  428.  
  429. void UAEWindow::WindowActivated(bool active)
  430. {
  431.     inwindow = active;
  432. }
  433.  
  434.  
  435. /*
  436.  *  Bitmap view constructor
  437.  */
  438.  
  439. BitmapView::BitmapView(BRect frame, BBitmap *bitmap) : BView(frame, "", B_FOLLOW_NONE, B_WILL_DRAW)
  440. {
  441.     the_bitmap = bitmap;
  442. }
  443.  
  444.  
  445. /*
  446.  *  Blit the bitmap
  447.  */
  448.  
  449. void BitmapView::Draw(BRect update)
  450. {
  451.     DrawBitmap(the_bitmap, update, update);
  452. }
  453.  
  454. void BitmapView::Draw(BRect from, BRect to)
  455. {
  456.     DrawBitmap(the_bitmap, from, to);
  457. }
  458.  
  459.  
  460. /*
  461.  *  Start main emulation thread
  462.  */
  463.  
  464. void Emulator::Run(void)
  465. {
  466.     // Initialize everything    
  467.     produce_sound = FALSE;
  468.     init_joystick();
  469.     keybuf_init ();    
  470.     memory_init();
  471.     custom_init();
  472.     DISK_init();
  473.     init_m68k();
  474.     MC68000_reset();
  475.  
  476.     // Start the emulation thread
  477.     the_thread = spawn_thread(thread_invoc, "UAE 68000", B_NORMAL_PRIORITY, this);
  478.     resume_thread(the_thread);
  479.     thread_running = TRUE;
  480. }
  481.  
  482.  
  483. /*
  484.  *  Stop main emulation thread
  485.  */
  486.  
  487. void Emulator::Quit(void)
  488. {
  489.     // Kill the thread if it is running
  490.     if (thread_running) {
  491.         kill_thread(the_thread);
  492.         thread_running = FALSE;
  493.     }
  494.  
  495.     close_joystick();
  496. }
  497.  
  498.  
  499. /*
  500.  *  The thread's main function
  501.  */
  502.  
  503. long Emulator::thread_invoc(Emulator *obj)
  504. {
  505.     obj->thread_func();
  506.     return 0;
  507. }
  508.  
  509. void Emulator::thread_func(void)
  510. {
  511.     // This jumps to MC68000_run() and executes the main loop
  512.     debug();
  513.     thread_running = FALSE;
  514. }
  515.  
  516.  
  517. /*
  518.  *  Redraw a line
  519.  */
  520.  
  521. void flush_line(int y)
  522. {
  523.     if (window_open) {
  524.         bitmap_window->Lock();
  525.         bitmap_view->Draw(BRect(0, y, hpixels-1, y));
  526.         bitmap_window->Unlock();
  527.     }
  528. }
  529.  
  530.  
  531. /*
  532.  *  Redraw a block
  533.  */
  534.  
  535. void flush_block(int ystart, int ystop)
  536. {
  537.     int xs = use_lores ? prev_max_diwstop - 328 : 0;
  538.  
  539.     if (window_open) {
  540.         bitmap_window->Lock();
  541.         bitmap_view->Draw(BRect(xs, ystart, hpixels+xs-1, ystop), BRect(0, ystart, hpixels-1, ystop));
  542.         bitmap_window->Unlock();
  543.     }
  544. }
  545.  
  546.  
  547. /*
  548.  *  Redraw the screen
  549.  */
  550.  
  551. void flush_screen(int ystart, int ystop)
  552. {
  553. }
  554.  
  555.  
  556. /*
  557.  *  Poll mouse and keyboard
  558.  */
  559.  
  560. void handle_events(void)
  561. {
  562.     key_info the_key_info;
  563.     int be_code, be_byte, be_bit, amiga_code;
  564.     BPoint mouse_point;
  565.     ulong mouse_buttons;
  566.  
  567.     // Keyboard
  568.     if (window_open && inwindow) {
  569.         bitmap_window->Lock();
  570.         bitmap_view->GetKeys(&the_key_info, FALSE);
  571.         bitmap_window->Unlock();
  572.  
  573.         for (be_code=0; be_code<0x80; be_code++) {
  574.             be_byte = be_code >> 3;
  575.             be_bit = 1 << (~be_code & 7);
  576.  
  577.             // Key state changed?
  578.             if ((the_key_info.key_states[be_byte] & be_bit)
  579.                  != (old_key_info.key_states[be_byte] & be_bit)) {
  580.  
  581.                 amiga_code = keycode2amiga[be_code];
  582.                 if (the_key_info.key_states[be_byte] & be_bit) {
  583.  
  584.                     // Key pressed
  585.                     if (amiga_code == AK_mousestuff)
  586.                         togglemouse();
  587.                     else
  588.                         record_key(amiga_code << 1);
  589.                 } else {
  590.  
  591.                     // Key released
  592.                     record_key((amiga_code << 1) | 1);
  593.                 }
  594.             }
  595.         }        
  596.         old_key_info = the_key_info;
  597.  
  598.         // "Affengriff"
  599.         if ((the_key_info.key_states[0x5c >> 3] & (1 << (~0x5c & 7)))
  600.          && (the_key_info.key_states[0x5d >> 3] & (1 << (~0x5d & 7)))
  601.          && (the_key_info.key_states[0x5f >> 3] & (1 << (~0x5f & 7))))
  602.             MC68000_reset();
  603.  
  604.         // Scroll lock toggles inhibit_frame
  605.         inhibit_frame = the_key_info.key_states[0x0f >> 3] & (1 << (~0x0f & 7));
  606.     }
  607.  
  608.     // Mouse
  609.     if (window_open && inwindow) {
  610.         bitmap_window->Lock();
  611.         bitmap_view->GetMouse(&mouse_point, &mouse_buttons, FALSE);
  612.         bitmap_window->Unlock();
  613.         lastmx = mouse_point.x;
  614.         lastmy = mouse_point.y;
  615.  
  616.         buttonstate[0] = mouse_buttons & B_PRIMARY_MOUSE_BUTTON;
  617.         buttonstate[1] = mouse_buttons & B_TERTIARY_MOUSE_BUTTON;
  618.         buttonstate[2] = mouse_buttons & B_SECONDARY_MOUSE_BUTTON;
  619.     }
  620. }
  621.  
  622.  
  623. int debuggable(void)
  624. {
  625.     return TRUE;
  626. }
  627.  
  628. int needmousehack(void)
  629. {
  630.     return TRUE;
  631. }
  632.  
  633. void LED(int on)
  634. {
  635. }
  636.